package com.gutai.admin.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.gutai.admin.biz.OrderStatusHelper;
import com.gutai.admin.common.entity.dto.OrderRequestParamsDto;
import com.gutai.admin.dao.IOrderDao;
import com.gutai.admin.dao.IOrderExpressDao;
import com.gutai.admin.dao.IOrderGoodsDao;
import com.gutai.admin.entity.Order;
import com.gutai.admin.entity.OrderExpress;
import com.gutai.admin.entity.OrderGoods;
import com.gutai.admin.service.IOrderService;


/**
 * 
 * 
 * 
 * <pre>
 * HISTORY
 * ****************************************************************************
 *  ID    DATE            PERSON            REASON
 *  1     2019年1月29日         la.01367604           Create
 * ****************************************************************************
 * </pre>
 * 
 * @author la.01367604
 * @version 1.0
 */
@Service
public class OrderService implements IOrderService {

    @Autowired
    private IOrderDao orderDao;
    @Autowired
    private IOrderExpressDao orderExpressDao;
    @Autowired
    private IOrderGoodsDao orderGoodsDao;

    @Override
    public List<Order> getAll() {
        return orderDao.findAll();
    }

    @Override
    public Page<Order> getList(int startPage, int pageSize) {
        return orderDao.queryPage(startPage, pageSize);
    }

    @Override
    public Page<Order> getList(OrderRequestParamsDto paramsDto) {
//        Map<String, Object> condsMap = new HashMap<>();
//        if (paramsDto.getOrderStatus() != null) {
//            condsMap.put("order_status", paramsDto.getOrderStatus());
//        }
//        if (paramsDto.getOrderStartTime() != null && paramsDto.getOrderEndTime() != null) {
//             condsMap.put("add_time", ">" +  paramsDto.getOrderStartTime());
//             condsMap.put("add_time", "<" + paramsDto.getOrderEndTime());
//        }
//        return orderDao.queryListByPage(Order.class, condsMap, paramsDto.getStartPage(), paramsDto.getPageSize());
        
//        EntityManager em = orderDao.getEntityManager();
//        CriteriaBuilder builder = em.getCriteriaBuilder();
//        CriteriaQuery<Order> query = builder.createQuery(Order.class);
//        Root<Order> root = query.from(Order.class);
//        if (paramsDto.getOrderStatus() != null) {
//            query.where(builder.and(builder.equal(root.get("order_status"), paramsDto.getOrderStatus())));
//        }
//        if (paramsDto.getOrderStartTime() != null && paramsDto.getOrderEndTime() != null) {
//            query.where(builder.and(
//                builder.lessThanOrEqualTo(root.get("add_time"), paramsDto.getOrderEndTime()),
//                builder.greaterThanOrEqualTo(root.get("add_time"), paramsDto.getOrderStartTime())));
//        }
//        return em.createQuery(query).getResultList();
        Page<Order> orderPage = null;
        Sort sort = new Sort(Sort.Direction.DESC, "addTime");
        if (paramsDto.getOrderStatus() != null || paramsDto.getOrderStartTime()!=null ||paramsDto.getOrderEndTime()!=null) {
            Specification<Order> spec= new Specification<Order>() {

                @Override
                public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicates = new ArrayList<>();
                    if (paramsDto.getOrderStatus() != null) {
                        predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("orderStatus"), paramsDto.getOrderStatus())));
                    }
                    if (paramsDto.getOrderStartTime() != null) {
                        predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("addTime"), paramsDto.getOrderStartTime() / 1000000));
                    }
                    if (paramsDto.getOrderEndTime() != null) {
                        predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("addTime"), paramsDto.getOrderEndTime() / 1000000));
                    }
                    return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
                } 

            };
            orderPage = orderDao.queryPageWithSpec(spec, paramsDto.getStartPage(), paramsDto.getPageSize(), sort);
        } else {
            orderPage = orderDao.queryPage(paramsDto.getStartPage(), paramsDto.getPageSize(), sort);
        }
        orderPage.getContent().stream().forEach(order -> convertOrder2Ui(order));
        return orderPage;
    }

    private void convertOrder2Ui(Order entity) {
        String status = OrderStatusHelper.getOrderStatusByCode(entity.getOrderStatus());
        entity.setOrderStatusName(status);
    }

    @Override
    public void add(Order entity) {
        orderDao.save(entity);
    }

    @Override
    public void update(Order entity) {
        orderDao.saveAndFlush(entity);
    }

    @Override
    public Order findById(int id) {
        Order order = orderDao.findById(id);
        convertOrder2Ui(order);
        return order;
    }

    @Override
    public void delete(int id) {
        orderDao.deleteById(id);
    }

    @Override
    public List<OrderExpress> getOrderExpressList() {
        return orderExpressDao.findAll();
    }

    @Override
    public Page<OrderExpress> getOrderExpressList(int startPage, int pageSize) {
        return orderExpressDao.queryPage(startPage, pageSize);
    }

    @Override
    public void addOrderExpress(OrderExpress entity) {
        orderExpressDao.save(entity);
    }

    @Override
    public void updateOrderExpress(OrderExpress entity) {
        orderExpressDao.saveAndFlush(entity);
    }

    @Override
    public OrderExpress findOrderExpressById(int id) {
        return orderExpressDao.findById(id);
    }

    @Override
    public List<OrderExpress> findOrderExpressByOrderId(int orderId) {
        return orderExpressDao.findByOrderId(orderId);
    }

    @Override
    public void deleteOrderExpress(int id) {
        orderExpressDao.deleteById(id);
    }

    @Override
    public List<OrderGoods> getOrderGoodsList() {
        return orderGoodsDao.findAll();
    }

    @Override
    public void addOrderGoods(OrderGoods entity) {
        orderGoodsDao.save(entity);
    }

    @Override
    public void updateOrderGoods(OrderGoods entity) {
        orderGoodsDao.saveAndFlush(entity);
    }

    @Override
    public OrderGoods findOrderGoodsById(int id) {
        return orderGoodsDao.findById(id);
    }

    @Override
    public List<OrderGoods> findOrderGoodsByOrderId(int orderId) {
        return orderGoodsDao.findByOrderId(orderId);
    }

    @Override
    public void deleteOrderGoods(int id) {
        orderGoodsDao.deleteById(id);
    }

}
